#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/types.h>
#define NUM 1024
#define COM_NUM 64
#define SEP " "
char cwd[1024];
char envpath[1024];
int lastcode=0;
//#define Debug 1
const char*getUserName()
{
    char*user=getenv("USER");
    return user;
}
const char*getHostName()
{
    char*host=getenv("HOSTNAME");
    return host;
}
const char*getPwd()
{
    char*pwd=getenv("PWD");
    return pwd;
}
int getUserCommand(char*command,int num)
{

    printf("[%s@%s %s]# ",getUserName(),getHostName(),getPwd());
    //scanf("%s",commandname);
    char*r=fgets(command,num,stdin);
    if(r==NULL) return -1;
    //abcd\n
    command[strlen(command)-1]='\0';
    return strlen(command);

}
void commandSplit(char*in,char*out[])
{
    int argc=0;
    out[argc++]=strtok(in,SEP);
    while(out[argc++]=strtok(NULL,SEP));
#ifdef Debug
    for(int i=0;i<COM_NUM;i++)
    {
        if(out[i]==NULL) break;
        printf("%s ",out[i]);
    }
#endif
}
int execute(char*argv[])
{
    
        int status=0;
         pid_t id=fork();//肯定是交给子进程执行命令的，要不然自己都被替换了，就没办法跑了
         if(id<0)
         {
             return -1;
         }
         if(id==0)
         {
             //exec command
             execvp(argv[0],argv);
             exit(0);//替换失败了，就直接终止
         }
         else{
                 pid_t wid=waitpid(id,&status,0);
                 lastcode=WEXITSTATUS(status);
         }
         return 0;
}
void cd(char*path)
{   
    chdir(path);
    char tmp[1024];
    getcwd(tmp,sizeof(tmp));
    sprintf(cwd,"PWD=%s",tmp);
    putenv(cwd);
}
char*gethome()
{
    char*home=getenv("HOME");
    return home;
}
int doBuildin(char*argv[])
{
    char*path=NULL;
    if(strcmp(argv[0],"cd")==0)
    {
        if(argv[1]==NULL) path=gethome();
       else  path=argv[1];
        cd(path);
        return 1;
    }
    else if(strcmp(argv[0],"export")==0)
    {
        if(argv[1]==NULL) return 1;
        strcpy(envpath,argv[1]);
        putenv(envpath);//??
        return 1;
    }
    else if(strcmp(argv[0],"echo")==0)
    {
        if(*(argv[1])=='$'&&strlen(argv[1])>1){
           char*str=argv[1]+1;//$PATH $?
           if(strcmp(str,"?")==0)
           {
               printf("%d\n",lastcode);
               lastcode=0;
           }
           else{
               char*envalue=getenv(str);
               if(envalue)printf("%s\n",getenv(str));
               else printf("\n");
           }
        }
        else{
            printf("%s\n",argv[1]);
        }
        return 1;
    }
    else{}
    return 0;

}
int main()
{
    while(1){
         char commandname[NUM];
         char*argv[COM_NUM];
         //1、打印提示符&&获取用户命令字符串
         int n=getUserCommand(commandname,sizeof(commandname));
         if(n<=0) continue;
         //2、分割字符串
         commandSplit(commandname,argv);
         //3、检查&&执行内建命令
         int ret=doBuildin(argv);
         if(ret) continue;
         //4、执行对应的命令
         execute(argv);
         //printf("%s\n",commandname);
    }
    return 0;
}
